import { EventEmitter } from 'events';
import os from 'os';
import { Request, Response } from 'express';

interface PerformanceMetrics {
  timestamp: number;
  cpu: number;
  memory: {
    total: number;
    used: number;
    free: number;
    heapTotal: number;
    heapUsed: number;
  };
  requests: {
    total: number;
    active: number;
    errors: number;
  };
  response: {
    avgTime: number;
    p95Time: number;
    p99Time: number;
  };
  database: {
    connections: number;
    queryCount: number;
    avgQueryTime: number;
  };
  cache: {
    hits: number;
    misses: number;
    ratio: number;
  };
}

interface RequestMetrics {
  path: string;
  method: string;
  startTime: number;
  duration?: number;
  status?: number;
  error?: Error;
}

export class MonitorService {
  private static instance: MonitorService;
  private metrics: PerformanceMetrics;
  private requestMetrics: RequestMetrics[] = [];
  private readonly eventEmitter = new EventEmitter();
  private readonly metricsHistory: PerformanceMetrics[] = [];
  private readonly historyLimit = 1000; // 保留最近1000条记录
  private collectionInterval: NodeJS.Timeout | null = null;

  private constructor() {
    this.metrics = this.initializeMetrics();
    this.startCollection();
  }

  public static getInstance(): MonitorService {
    if (!MonitorService.instance) {
      MonitorService.instance = new MonitorService();
    }
    return MonitorService.instance;
  }

  // 初始化指标
  private initializeMetrics(): PerformanceMetrics {
    return {
      timestamp: Date.now(),
      cpu: 0,
      memory: {
        total: os.totalmem(),
        used: 0,
        free: os.freemem(),
        heapTotal: 0,
        heapUsed: 0
      },
      requests: {
        total: 0,
        active: 0,
        errors: 0
      },
      response: {
        avgTime: 0,
        p95Time: 0,
        p99Time: 0
      },
      database: {
        connections: 0,
        queryCount: 0,
        avgQueryTime: 0
      },
      cache: {
        hits: 0,
        misses: 0,
        ratio: 0
      }
    };
  }

  // 启动指标收集
  private startCollection(): void {
    if (this.collectionInterval) {
      clearInterval(this.collectionInterval);
    }

    this.collectionInterval = setInterval(() => {
      this.collectMetrics();
    }, 5000); // 每5秒收集一次
  }

  // 收集系统指标
  private async collectMetrics(): Promise<void> {
    const cpuUsage = await this.getCPUUsage();
    const memUsage = process.memoryUsage();

    this.metrics = {
      ...this.metrics,
      timestamp: Date.now(),
      cpu: cpuUsage,
      memory: {
        total: os.totalmem(),
        used: os.totalmem() - os.freemem(),
        free: os.freemem(),
        heapTotal: memUsage.heapTotal,
        heapUsed: memUsage.heapUsed
      }
    };

    // 更新响应时间统计
    const responseTimes = this.requestMetrics
      .filter(m => m.duration !== undefined)
      .map(m => m.duration!);

    if (responseTimes.length > 0) {
      responseTimes.sort((a, b) => a - b);
      this.metrics.response = {
        avgTime: responseTimes.reduce((a, b) => a + b, 0) / responseTimes.length,
        p95Time: responseTimes[Math.floor(responseTimes.length * 0.95)],
        p99Time: responseTimes[Math.floor(responseTimes.length * 0.99)]
      };
    }

    // 清理旧的请求指标
    const tenMinutesAgo = Date.now() - 10 * 60 * 1000;
    this.requestMetrics = this.requestMetrics.filter(
      m => m.startTime > tenMinutesAgo
    );

    // 保存历史记录
    this.metricsHistory.push({ ...this.metrics });
    if (this.metricsHistory.length > this.historyLimit) {
      this.metricsHistory.shift();
    }

    this.eventEmitter.emit('metrics', this.metrics);
  }

  // 获取CPU使用率
  private async getCPUUsage(): Promise<number> {
    const startUsage = process.cpuUsage();
    await new Promise(resolve => setTimeout(resolve, 100));
    const endUsage = process.cpuUsage(startUsage);
    return (endUsage.user + endUsage.system) / 1000000;
  }

  // 请求监控中间件
  public createMiddleware() {
    return (req: Request, res: Response, next: Function) => {
      const metric: RequestMetrics = {
        path: req.path,
        method: req.method,
        startTime: Date.now()
      };

      this.requestMetrics.push(metric);
      this.metrics.requests.active++;
      this.metrics.requests.total++;

      const cleanup = () => {
        this.metrics.requests.active--;
        metric.duration = Date.now() - metric.startTime;
        metric.status = res.statusCode;
        
        if (res.statusCode >= 400) {
          this.metrics.requests.errors++;
        }
      };

      res.on('finish', cleanup);
      res.on('error', (error: Error) => {
        metric.error = error;
        cleanup();
      });

      next();
    };
  }

  // 数据库查询监控
  public recordDatabaseQuery(duration: number): void {
    this.metrics.database.queryCount++;
    this.metrics.database.avgQueryTime = 
      (this.metrics.database.avgQueryTime * (this.metrics.database.queryCount - 1) + duration) /
      this.metrics.database.queryCount;
  }

  // 缓存命中监控
  public recordCacheHit(): void {
    this.metrics.cache.hits++;
    this.updateCacheRatio();
  }

  public recordCacheMiss(): void {
    this.metrics.cache.misses++;
    this.updateCacheRatio();
  }

  private updateCacheRatio(): void {
    const total = this.metrics.cache.hits + this.metrics.cache.misses;
    this.metrics.cache.ratio = total > 0 ? this.metrics.cache.hits / total : 0;
  }

  // 获取当前指标
  public getCurrentMetrics(): PerformanceMetrics {
    return { ...this.metrics };
  }

  // 获取历史指标
  public getMetricsHistory(minutes: number = 30): PerformanceMetrics[] {
    const since = Date.now() - minutes * 60 * 1000;
    return this.metricsHistory.filter(m => m.timestamp >= since);
  }

  // 监听指标更新
  public onMetricsUpdate(callback: (metrics: PerformanceMetrics) => void): void {
    this.eventEmitter.on('metrics', callback);
  }

  // 告警检查
  public checkAlerts(): void {
    // CPU使用率超过80%
    if (this.metrics.cpu > 80) {
      this.eventEmitter.emit('alert', {
        type: 'cpu',
        message: `High CPU usage: ${this.metrics.cpu.toFixed(2)}%`
      });
    }

    // 内存使用率超过90%
    const memoryUsage = (this.metrics.memory.used / this.metrics.memory.total) * 100;
    if (memoryUsage > 90) {
      this.eventEmitter.emit('alert', {
        type: 'memory',
        message: `High memory usage: ${memoryUsage.toFixed(2)}%`
      });
    }

    // 错误率超过5%
    const errorRate = (this.metrics.requests.errors / this.metrics.requests.total) * 100;
    if (errorRate > 5) {
      this.eventEmitter.emit('alert', {
        type: 'error_rate',
        message: `High error rate: ${errorRate.toFixed(2)}%`
      });
    }

    // 响应时间超过2秒
    if (this.metrics.response.p95Time > 2000) {
      this.eventEmitter.emit('alert', {
        type: 'response_time',
        message: `Slow response time (P95): ${this.metrics.response.p95Time}ms`
      });
    }
  }

  // 停止监控
  public stop(): void {
    if (this.collectionInterval) {
      clearInterval(this.collectionInterval);
      this.collectionInterval = null;
    }
  }
}
